package org.ccay.core.xml;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.ccay.core.util.exception.FileProcessException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXException;

/**
 * 大型xml文件读取处理模板类,只要继续此类，重写onStart, onEnd方法 Created：2013-8-5
 * 
 * @author chaowangbang
 * @version:
 */
public class BigXmlReadHandler implements ElementHandler {
	private String[] xmlElementPath; // 处理的节点路径
	private InputStream inputStream; // 输入流
	private static final String XML_PROCESS = "ccay.core.00060002";

	public BigXmlReadHandler() {

	}

	public BigXmlReadHandler(String[] xmlElementPath, InputStream inputStream) {
		super();
		this.xmlElementPath = xmlElementPath;
		this.inputStream = inputStream;
	}
	
	public BigXmlReadHandler(String[] xmlElementPath, String filePath) {
		super();
		this.xmlElementPath = xmlElementPath;
		try {
			this.inputStream = new BufferedInputStream(new FileInputStream(filePath));
		} catch (FileNotFoundException e) {
			throw new FileProcessException(XML_PROCESS, e);
		}
	}

	/**
	 * 调用此方法，开始逐行读取文件,读完后返回Document对象
	 * 
	 * @return
	 */
	public Document startRead(){
		Document doc = null;
		try {
			SAXReader reader = new SAXReader();
			for (String path : xmlElementPath) {
				reader.addHandler(path, this);
			}
			reader.setDefaultHandler(new PruningElementHandler());
			reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
			doc = reader.read(inputStream);
		} catch (DocumentException e) {
			throw new FileProcessException(XML_PROCESS, e);
		} catch (SAXException e) {
			e.printStackTrace();
		}
		return doc;
	}
	/*
	 * （非 Javadoc）
	 * @see org.dom4j.ElementHandler#onEnd(org.dom4j.ElementPath)
	 */
	public void onEnd(ElementPath elementPath) {
		elementPath.getCurrent().detach();

	}
	/*
	 * （非 Javadoc）
	 * @see org.dom4j.ElementHandler#onStart(org.dom4j.ElementPath)
	 */
	public void onStart(ElementPath elementPath) {
		elementPath.getCurrent().detach();
	}

	/**
	 * 默认处理器
	 * 
	 */
	class PruningElementHandler implements ElementHandler {
		/*
		 * （非 Javadoc）
		 * @see org.dom4j.ElementHandler#onEnd(org.dom4j.ElementPath)
		 */
		public final void onEnd(ElementPath elementPath) {
			Element element = elementPath.getCurrent();
			if (element != null) {
				element.detach();
			}
		}
		/*
		 * （非 Javadoc）
		 * @see org.dom4j.ElementHandler#onStart(org.dom4j.ElementPath)
		 */
		public final void onStart(ElementPath elementPath) {
			Element element = elementPath.getCurrent();
			if (element != null) {
				element.detach();
			}

		}

	}
	public String[] getXmlElementPath() {
		return xmlElementPath;
	}

	public void setXmlElementPath(String[] xmlElementPath) {
		this.xmlElementPath = xmlElementPath;
	}

	public InputStream getInputStream() {
		return inputStream;
	}
}
